package vn.lumi.smarthome.network;

import java.io.UnsupportedEncodingException;

import vn.lumi.smarthome.LumiHome;
import vn.lumi.smarthome.R;
import vn.lumi.smarthome.io.database.TBL_DeviceScene;
import vn.lumi.smarthome.io.database.TBL_DeviceState;
import vn.lumi.smarthome.io.database.TBL_Scene;
import vn.lumi.smarthome.io.model.Device;
import vn.lumi.smarthome.io.model.Scene;
import vn.lumi.smarthome.io.model.Time;
import vn.lumi.smarthome.ulti.Preference;

import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Parcel;

public class CreateScene extends AppMsg{

	//attributes
	private String sceneName = "";
	private int roomID = 0;
	private int Scene_id = 0;
	private int mode = 0;
	private Time turnOnTime = new Time();
	private int[] deviceIDList = null;
	private int[] deviceStateList = null;
	private int[] RGBIDList = null;
	private int[] RGBStateList = null;
	private int NumOfDevices = 0;
	private int NumOfRGBs = 0;
	private int newConfigVersion = 0;
	
	public CreateScene(int Msg_id, int uid, int sid, String name, int roomid, int mode, Time time, int[] DeviceIDList, int[] DeviceStateList, int[] rgbIDList, int[] rgbStateList) {
		super(NetMessage.CMD_APP_CREATE_SCENE, Msg_id, uid, sid);
		// TODO Auto-generated constructor stub
		sceneName = name;
		roomID = roomid;
		Scene_id = 0;
		deviceIDList = DeviceIDList;
		deviceStateList = DeviceStateList;
		RGBIDList = rgbIDList;
		RGBStateList = rgbStateList;
		if(RGBIDList != null) NumOfRGBs = RGBIDList.length;
		if(deviceIDList != null) NumOfDevices = deviceIDList.length;
		this.mode = mode;
		this.turnOnTime = time;
	}

	@Override
	public byte[] generateByteArray() {
		// TODO Auto-generated method stub
		byte[] result = new byte[41 + NumOfDevices*2 + NumOfRGBs*4];
		result[0] = (byte) this.Cmd_id;
		result[1] = (byte) this.Msg_id;
		result[2] = (byte) this.user_id;
		result[3] = (byte) this.session_id;
		result[4] = (byte) this.Scene_id;
		result[5] = (byte) this.roomID;
		byte[] name = null;
		try {
			name = this.sceneName.getBytes("UTF-16BE");
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		for(int i = 0;i<30;i++){
			if(i>=name.length) result[6+i] = 0;
			else result[6+i] = name[i];
		}
		result[36] = (byte) this.mode;
		result[37] = (byte) this.turnOnTime.getHour();
		result[38] = (byte) this.turnOnTime.getMinute();
		result[39] = (byte) NumOfDevices;
		result[40] = (byte) NumOfRGBs;
		for(int i = 0; i<NumOfDevices; i++){
			result[41+2*i] = (byte) deviceIDList[i];
			result[42+2*i] = (byte) deviceStateList[i];
		}
		int startPos = 41+2*NumOfDevices;
		for(int i = 0; i<NumOfRGBs; i++){
			result[startPos+4*i] = (byte) RGBIDList[i];
			result[startPos+4*i+1] = (byte) RGBStateList[3*i];
			result[startPos+4*i+2] = (byte) RGBStateList[3*i+1];
			result[startPos+4*i+3] = (byte) RGBStateList[3*i+2];
		}
		return result;
	}

	@Override
	public int describeContents() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public void writeToParcel(Parcel dest, int flags) {
		
		// TODO Auto-generated method stub
		dest.writeInt(this.Cmd_id);
		dest.writeInt(this.length);
		dest.writeInt(this.Msg_id);
		dest.writeInt(this.session_id);
		dest.writeInt(this.user_id);
		dest.writeInt(this.Scene_id);
		dest.writeInt(roomID);
		dest.writeString(sceneName);
		dest.writeInt(this.mode);
		dest.writeInt(this.turnOnTime.getHour());
		dest.writeInt(this.turnOnTime.getMinute());
		
		dest.writeIntArray(deviceIDList);
		dest.writeIntArray(deviceStateList);		
		dest.writeIntArray(this.RGBIDList);
		dest.writeIntArray(RGBStateList);
		dest.writeInt(this.NumOfDevices);
		dest.writeInt(this.NumOfRGBs);
	}

	@Override
	public void doIfSendSuccessful(Context context) {
		// TODO Auto-generated method stub
		//save scene into database
		if(Scene_id == 0x00){
			//inform UI
		    Intent intent = new Intent();
		    intent.setAction(context.getString(R.string.vn_lumi_smarthome_create_scene_overload));
		    context.sendBroadcast(intent);
			return;
		}
		ContentValues values = new ContentValues();
		values.put(TBL_Scene.NAME, sceneName);
		values.put(TBL_Scene.ROOM_ID, roomID);
		values.put(TBL_Scene.STATE, Scene.SCENE_STATE_OFF);
		values.put(TBL_Scene._ID, this.Scene_id);
		values.put(TBL_Scene.MODE, this.mode);
		values.put(TBL_Scene.HOUR, this.turnOnTime.getHour());
		values.put(TBL_Scene.MINUTE, this.turnOnTime.getMinute());
		context.getContentResolver().insert(TBL_Scene.CONTENT_URI_SCENE, values);
		
		//save device states
			//normal devices
		for(int i=0;i<NumOfDevices;i++){
			//insert device state
			ContentValues  contentValues=new ContentValues();
			contentValues.put(TBL_DeviceState.VALUE, deviceStateList[i]);
			contentValues.put(TBL_DeviceState.BLIND_STATE, Device.DEVICE_STATE_BLIND_STATE_STOPPED);
			Uri uri2= context.getContentResolver().insert(TBL_DeviceState.CONTENT_URI_DEVICE_STATE, contentValues);
			int state_id=Integer.parseInt(uri2.getLastPathSegment());
			
			//(3) Insert to DeviceScene
			contentValues.clear();
			contentValues.put(TBL_DeviceScene.DEVICE_ID,deviceIDList[i]);
			contentValues.put(TBL_DeviceScene.SCENE_ID,this.Scene_id);
			contentValues.put(TBL_DeviceScene.STATE_ID,state_id);
			context.getContentResolver().insert(TBL_DeviceScene.CONTENT_URI_DEVICE_SCENE, contentValues);
		}
			//rgbs
		for(int i=0;i<this.NumOfRGBs;i++){
			//insert device state
			ContentValues  contentValues=new ContentValues();
			int color = this.RGBStateList[3*i] * 256*256 + RGBStateList[3*i+1] *256 + RGBStateList[3*i+2];
			contentValues.put(TBL_DeviceState.RGB, color);
			Uri uri2= context.getContentResolver().insert(TBL_DeviceState.CONTENT_URI_DEVICE_STATE, contentValues);
			int state_id=Integer.parseInt(uri2.getLastPathSegment());
			
			//(3) Insert to DeviceScene
			contentValues.clear();
			contentValues.put(TBL_DeviceScene.DEVICE_ID,RGBIDList[i]);
			contentValues.put(TBL_DeviceScene.SCENE_ID,this.Scene_id);
			contentValues.put(TBL_DeviceScene.STATE_ID,state_id);
			context.getContentResolver().insert(TBL_DeviceScene.CONTENT_URI_DEVICE_SCENE, contentValues);
		}
		
		//save config in preferences
		LumiHome.HC_Config_ver = this.newConfigVersion;
		Preference.saveConfigVersion(context, this.newConfigVersion);
		
		
		//inform UI
	    Intent intent = new Intent();
	    intent.setAction(context.getString(R.string.vn_lumi_smarthome_create_scene_successful));
	    context.sendBroadcast(intent);
		
	}

	@Override
	public void doIfSendFail(Context context) {
		// TODO Auto-generated method stub
		//inform UI
	    Intent intent = new Intent();
	    intent.setAction(context.getString(R.string.vn_lumi_smarthome_create_scene_failed));
	    context.sendBroadcast(intent);
	}

	@Override
	public void readFromParcel(Parcel in) {
		// TODO Auto-generated method stub
		Cmd_id = in.readInt();
		length = in.readInt();
		Msg_id = in.readInt();
		session_id = in.readInt();
		user_id = in.readInt();
		Scene_id= in.readInt();
		roomID = in.readInt();
		sceneName = in.readString();
		mode = in.readInt();
		turnOnTime = new Time(in.readInt(), in.readInt());
		in.readIntArray(deviceIDList);
		in.readIntArray(deviceStateList);
		in.readIntArray(RGBIDList);
		in.readIntArray(RGBStateList);
		this.NumOfDevices = in.readInt();
		this.NumOfRGBs = in.readInt();
	}

	@Override
	public boolean isCorrectReply(byte[] input, int length) {
		// TODO Auto-generated method stub
		boolean result = false;
		AckScene ack = new AckScene();
		if(ack.isCorrectFormat(input, length)){
			ack.parseMessage(input, length);
			if(ack.getMsg_id() == this.Msg_id
					&&ack.getUserId() == this.getUid()) {
				this.Scene_id = ack.getSceneID();
				this.newConfigVersion = ack.getConfigVersion();
				result = true;
			}
		}
		return result;
	}

	/* (non-Javadoc)
	 * @see vn.lumi.smarthome.network.AppMsg#isCorrectBusy(byte[], int)
	 */
	@Override
	public boolean isCorrectBusy(byte[] input, int length) {
		// TODO Auto-generated method stub
		boolean result =false;
		HC_ACK_BUSY ack_busy = new HC_ACK_BUSY();
		if(ack_busy.isCorrectFormatBusy(input, length)){
			ack_busy.parseMessage(input, length);
			if(ack_busy.getMsg_id() == this.Msg_id) result = true;
		}
		return result; 
	}

	/* (non-Javadoc)
	 * @see vn.lumi.smarthome.network.AppMsg#doIfHcBusying()
	 */
	@Override
	public void doIfHcBusying() {
		// TODO Auto-generated method stub
		
	}

}
